angular.module('ionicApp.services', [])

.factory('localStorageService', function() {
    return {
        get: function(key, defaultValue) {
            var stored = localStorage[key];
            if (stored) {
                return angular.fromJson(stored);
            }
            return [];
        },
        update: function(key, value) {
            if (value) {
                localStorage[key] = angular.toJson(value);
            }
        },
        delete: function(key) {
            localStorage[key] = null;
        },
        clear: function() {
            localStorage.clear();
        }
    }
})

.factory('uTool', function() {
    return {
        inArray: function(item, arr) {
            if (!angular.isArray(arr)) {
                console.log("param is error");
                return false;
            }

            return arr.some(function(val) {
                return angular.equals(item, val);
            });
        },
        getRandom: function() {
            var code = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
                userId = Math.floor(Math.random() * 10000),
                ran = "",
                i;
            for (i = 0; i < 3; i++) {
                ran += code[Math.ceil(Math.random() * 26) - 1];
            }
            return ran + "_" + userId;
        },
        getNowDate: function() {
            var date = new Date(),
                nowDate = {
                    year: date.getFullYear(),
                    month: date.getMonth(),
                    day: date.getDay(),
                    week: date.getDay(),
                    hour: date.getHours(),
                    minute: date.getMinutes(),
                    second: date.getSeconds(),
                    str: date.toGMTString().substring(5, 25)
                };
            return nowDate;
        },
        arrayExt: function(arr1, arr2, deep) {
            var that = this,
                temp = [];

            angular.forEach(arr1, function(item, index) {
                temp.push(angular.copy(item));
            });

            angular.forEach(arr2, function(item, index) {
                // deep clone, if it is exist in array, not allow in again
                if (deep) {
                    if (!that.inArray(item, temp)) {
                        temp.push(angular.copy(item));
                    }
                } else {
                    temp.push(angular.copy(item));
                }
            });

            return temp;
        },
        regTest: (function() {
            var regMode = {
                imgFile: /^(image)/g,
                mobile: /^1(\d){10}$/,
                empty: /^\s*$/,
                notempty: /\S+/,
                email: /^\w+((-|\.)\w+)*\@\w+((-|\.)\w+)*\.\w+$/,
                decimal: /^-?(([1-9]\d*(\.\d+))|(0\.\d+))$/,
                int: /^-?\d+$/,
                positiveDecimal: /^(([1-9]\d*(\.\d+))|(0\.\d+))$/,
                positiveInt: /^[1-9]\d+$/,
                tel: /^(([0\+]\d{2,3}-)?(0\d{2,3})-)?(\d{7,8})(-(\d{3,}))?$/,
                url: /^(http[s]?:\/\/)?([\w-]+\.)+[\w-]+([\w-.\/?%&=]*)?$/,
                zipcode: /^\d{6}$/
            };

            return function(str, type) {
                if (type && regMode[type] && regMode[type].test(str)) {
                    return true;
                }
                return false;
            }
        })()
    }
})

.factory('diaryService', function(localStorageService, $http, uTool) {
    var diarys = [],
        cateID = [],
        activeIndex = 0;
    return {
        getXHRDiarys: function() {
            return $http.get('/data/diary/diary.json');
        },
        getDiarys: function(cate) {
            var res = [];

            if (diarys.length === 0) {
                diarys = localStorageService.get("Diarys");
            }

            angular.forEach(diarys, function(item, index) {
                item.cate === cate && res.push(item);
            });
            return res;
        },
        addDiary: function(obj) {
            if (!angular.isObject(obj)) {
                console.log("param is wrong type");
                return false;
            }
            var diary = obj || {};
            // if diary.cate is not in cateID, we will not add
            if (!uTool.inArray(diary.cate, cateID)) {
                console.log("it is unvariable cate");
                return false;
            }

            diarys.push({
                cate: diary.cate,
                title: diary.title,
                text: diary.text,
                image: diary.img,
                time: diary.time
            });

            this.cacheDiarys();
            return diarys;
        },
        delDiary: function(obj) {
            angular.forEach(diarys, function(item, index) {
                if (item.cate === obj.cate && item.title === obj.title && item.time === obj.time) {
                    this.splice(index, 1);
                }
            }, diarys);

            this.cacheDiarys();
            return diarys;
        },
        editDiary: function(oldObj, newObj) {
            angular.forEach(diarys, function(item, index) {
                if (item.cate === oldObj.cate && item.title === oldObj.title && item.time === oldObj.time) {
                    item.cate = newObj.cate;
                    item.title = newObj.title;
                    item.text = newObj.text;
                    item.image = newObj.image;
                }
            }, diarys);

            this.cacheDiarys();
            return diarys;
        },
        delDiarys: function(cate) {
            // delete one cate of diarys
            angular.forEach(diarys, function(item, index) {
                item.cate === cate && this.splice(index, 1);
            }, diarys);
            return diarys;
        },
        cacheDiarys: function() {
            localStorageService.update('Diarys', diarys);
        },
        getCateID: function() {
            if (cateID.length === 0) {
                cateID = localStorageService.get('DCates');
            }
            return angular.copy(cateID);
        },
        addCateID: function(cate) {
            if (uTool.inArray(cate, cateID)) {
                return false;
            }

            // get the cache prevent the frash
            if (cateID.length === 0) {
                var oldCate = localStorageService.get('DCates');
                angular.extend(cateID, oldCate);
            }

            cateID.push(cate);
            this.cacheCateID();
            return true;
        },
        delCateID: function(cate) {
            var that = this;
            if (!uTool.inArray(cate, cateID)) return false;
            angular.forEach(cateID, function(item, index) {
                if (item === cate) {
                    this.splice(index, 1);
                    that.delDiarys(item);
                }
            }, cateID);

            that.cacheCateID();
            that.cacheDiarys();
            return true;
        },
        editCateID: function(oldCate, newCate) {
            if (!newCate) return false;

            if (!uTool.inArray(oldCate, cateID)) {
                console.log("cateID does not exist");
                return false;
            }

            angular.forEach(cateID, function(item, index) {
                if (item === oldCate) {
                    cateID[index] = newCate;
                }
            });

            angular.forEach(diarys, function(item, index) {
                if (item[cate] === oldCate) {
                    diarys[index][cate] = newCate;
                }
            });

            this.cacheCateID();
            this.cacheDiarys();
            return true;
        },
        cacheCateID: function() {
            localStorageService.update('DCates', cateID);
        },
        delAllData: function() {
            // delete all cache of diarys and return a new array
            diarys = null;
            cateID = null;
            diarys = [];
            cateID = [];
            activeIndex = 0;
            this.cacheDiarys();
            this.cacheCateID();
            return diarys;
        },
        getIndex: function() {
            return activeIndex;
        },
        setIndex: function(num) {
            activeIndex = num;
            return true;
        }
    }
})

.factory('userService', function(localStorageService, $http, uTool) {
    var userList = [],
        userCate = [];
    return {
        getXHRUsers: function() {
            return $http.get();
        },
        getUsers: function(index) {
            if (userList.length === 0) {
                userList = localStorageService.get("Users");
                userCate = this.getUserCate();
            }
            return angular.copy(userList);
        },
        getUserCate: function() {
            userCate = []; // reset userCate
            angular.forEach(userList, function(item, index) {
                if (!uTool.inArray(item.cate, userCate)) {
                    userCate.push(item.cate);
                }
            });
            return angular.copy(userCate);
        },
        addUser: function(info) {
            if (!angular.isObject(info)) {
                console.log("typeof param is error");
                return false;
            }

            if (!uTool.inArray(info.cate, userCate)) {
                userList.push({
                    cate: info.cate,
                    users: [{
                        userid: uTool.getRandom(),
                        gender: info.gender,
                        name: info.name,
                        phone: info.phone,
                        cell: info.cell,
                        address: info.address,
                        email: info.email,
                        avatar: info.avatar,
                        cate: info.cate
                    }]
                });
            } else {
                angular.forEach(userList, function(item, index) {
                    if (item.cate === info.cate) {
                        item.users.push({
                            userid: uTool.getRandom(),
                            gender: info.gender,
                            name: info.name,
                            phone: info.phone,
                            cell: info.cell,
                            address: info.address,
                            email: info.email,
                            avatar: info.avatar,
                            cate: info.cate
                        });
                    }
                }, userList);
            }

            this.getUserCate();
            this.cacheUsers();
            return true;
        },
        delUser: function(info) {
            var cate = info.cate,
                temp = [],
                cateIndex = "";

            if (!uTool.inArray(cate, userCate)) {
                console.log("undefined this cate!");
                return false;
            }
            angular.forEach(userList, function(item, index) {
                if (item.cate === info.cate) {
                    temp = item.users;
                    cateIndex = index;
                }
            });
            // Array is reference object
            // if cate has change, param of userList will follow
            angular.forEach(temp, function(item, index) {
                if (item.userid === info.userid && item.name === info.name && item.phone === info.phone) {
                    this.splice(index, 1);
                    if (this.length === 0) {
                        userList.splice(cateIndex, 1);
                    }
                }
            }, temp);
            // when userList has change, release the memory
            temp = null;

            this.cacheUsers();
            return angular.copy(userList);
        },
        editUser: function(oldInfo, newInfo) {
            var cate = [],
                user = {},
                cateIndex = "",
                userIndex = "",
                oldCate = oldInfo.cate,
                newCate = newInfo.cate;

            if (!uTool.inArray(oldInfo.cate, userCate)) {
                console.log("undefined this cate!");
                return false;
            }

            // get cate which user belong to
            angular.forEach(userList, function(item, index) {
                if (item.cate === oldInfo.cate) {
                    cate = item.users;
                    cateIndex = index;
                }
            });

            // get user
            angular.forEach(cate, function(item, index) {
                if (item.userid === oldInfo.userid && item.name === oldInfo.name && item.phone === oldInfo.phone) {
                    user = item;
                    userIndex = index;
                }
            }, cate);

            // usercate has change
            if (oldInfo.cate !== newInfo.cate) {
                // delete the oldInfo
                userList[cateIndex]['users'].splice(userIndex, 1);
                if (userList[cateIndex]['users'].length === 0) {
                    userList.splice(cateIndex, 1);
                }
                // make sure if it is a new cate
                if (!uTool.inArray(newInfo.cate, userCate)) {
                    // add new cate, push newInfo into it
                    userList.push({
                        cate: newInfo.cate,
                        users: [{
                            userid: newInfo.userid,
                            gender: newInfo.gender,
                            name: newInfo.name,
                            phone: newInfo.phone,
                            cell: newInfo.cell,
                            address: newInfo.address,
                            email: newInfo.email,
                            avatar: newInfo.avatar,
                            cate: newInfo.cate
                        }]
                    })
                } else {
                    angular.forEach(userList, function(item, index) {
                        if (item.cate === newInfo.cate) {
                            item.users.push({
                                userid: newInfo.userid,
                                gender: newInfo.gender,
                                name: newInfo.name,
                                phone: newInfo.phone,
                                cell: newInfo.cell,
                                address: newInfo.address,
                                email: newInfo.email,
                                avatar: newInfo.avatar,
                                cate: newInfo.cate
                            })
                        }
                    });
                }
            } else {
                // change the user info, userid will not change
                user.gender = newInfo.gender;
                user.name = newInfo.name;
                user.phone = newInfo.phone;
                user.cell = newInfo.cell;
                user.address = newInfo.address;
                user.email = newInfo.email;
                user.avatar = newInfo.avatar;
                user.cate = newInfo.cate;
            }

            this.cacheUsers();
            this.getUserCate();
            return angular.copy(userList);
        },
        searchUser: function(str) {
            var temp = [];
            if (!uTool.regTest(str, "notempty")) {
                return [];
            }

            angular.forEach(userList, function(item, index) {
                // to search every user
                angular.forEach(item.users, function(user, i) {
                    var name = angular.lowercase(user.name)
                    if (name.search(angular.lowercase(str)) !== -1) {
                        temp.push(user);
                    }
                })
            });
            return angular.copy(temp);
        },
        cacheUsers: function() {
            localStorageService.update("Users", userList);
        }
    }
});
